package com.bifrost.util;

import com.bifrost.common.util.HttpRequestUtils;
import com.bifrost.constant.ImgConstant;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author 里昂
 * Create Class on 2018/4/26
 * @com.bifrost.common.util
 * @wechat-mall
 */
@Component
@Slf4j
public class FileUploadUtils {

    @Value("${upload.file.path:upload/}")
    String uploadPath;
    @Autowired
    public
    ImgConstant imgConstant;

    private static FileUploadUtils fileUploadUtils;

    public void setUploadPath(String uploadPath) {
        this.uploadPath = uploadPath;
    }
    public void setImgConstant(ImgConstant imgConstant) {
        this.imgConstant = imgConstant;
    }

    @PostConstruct
    public void init(){
        fileUploadUtils = this;
        fileUploadUtils.uploadPath = this.uploadPath;
        fileUploadUtils.imgConstant = this.imgConstant;
    }

    /**按照文件大小排序*/
    public static File[] orderByLength(String fliePath) {
        File[] files = new File(fliePath).listFiles();
        Arrays.sort(files, new Comparator< File>() {
            @Override
            public int compare(File f1, File f2) {
                long diff = f1.length() - f2.length();
                if (diff > 0){
                    return 1;
                }
                else if (diff == 0){
                    return 0;
                } else {
                    return -1;
                }
            }
            @Override
            public boolean equals(Object obj) {
                return true;
            }
        });
        return files;
    }


    /**按照文件名称排序*/
    public static File[] orderByName(String fliePath) {
        File[] files = new File(fliePath).listFiles();
        Arrays.sort(files,new Comparator< File>(){
            @Override
            public int compare(File o1, File o2) {
                if (o1.isDirectory() && o2.isFile()) {
                    return -1;
                }
                if (o1.isFile() && o2.isDirectory()) {
                    return 1;
                }
                return o1.getName().compareTo(o2.getName());
            }
        });
        return files;
    }
    /**按日期排序*/
    public static File[] orderByDate(String fliePath) {
        File[] files =  new File(fliePath).listFiles();
        Arrays.sort(files,new Comparator< File>(){
            @Override
            public int compare(File f1, File f2) {
                long diff = f1.lastModified() - f2.lastModified();
                if (diff > 0) {
                    return 1;
                }
                else if (diff == 0) {
                    return 0;
                } else {
                    return -1;
                }
            }
            @Override
            public boolean equals(Object obj) {
                return true;
            }

        });
        return files;
    }


    /**
     * 上传文件图片
     * @param imgStr 图片Base64字符串
     * @param initDirectory 上传路径位置   /product/img
     * @param key null/main/detail/ 200/450.. 图片切图规格
     * @return 相对访问路径地址
     * @throws IOException
     */
    @Deprecated/** 电器项目照搬过来.*/
    public static String toFiles(String imgStr, String initDirectory , String key) throws IOException {

        String suffix = "";
        ByteArrayInputStream is = null;
        for (Map.Entry<String,String> entry : fileUploadUtils.imgConstant.imgSupportType.entrySet()){
            String imgBase64Type = entry.getValue();
            if(imgStr.startsWith(imgBase64Type)){
                suffix = entry.getKey();
                imgStr = imgStr.replace(imgBase64Type, "");
                BASE64Decoder decoder = new BASE64Decoder();
                byte[] bytes = decoder.decodeBuffer(imgStr);
                is = new ByteArrayInputStream(bytes);
                //BufferedImage read = ImageIO.read(is); 获取图片参数 可以做限制
                break;
            }
        }
        Assert.notNull(is,"The image upload format is unsupported..");

        File toFile = notExistMkdirs(initDirectory,key);
        File[] files = toFile.listFiles();
        /*Integer count=0;
        //时间排序 获取最后上传的图片
        if(ArrayUtils.isNotEmpty(files)){
            files = FileUploadUtils.orderByDate(toFile.getAbsolutePath());
            files = Arrays.stream(files).filter(file -> !file.isDirectory()).collect(Collectors.toList()).toArray(new File[]{});
            if(ArrayUtils.isNotEmpty(files)){
                count = Integer.parseInt(files[files.length - 1].getName().split("\\.")[0]);
                count++;
            }
        }*/
        String fileName = String.format("%s.%s", UUID.randomUUID().toString().replaceAll("-",""),suffix);
        toFile = new File(toFile,fileName);

        // 主图详情图不切
        if (StringUtils.isBlank(key)||"detail".equalsIgnoreCase(key)||"main".equalsIgnoreCase(key)){
            FileUtils.copyToFile(is,toFile);
        }else {
            Integer size=null;
            try {
                size= Integer.valueOf(key);
            } catch (NumberFormatException e) {
                log.warn("转换异常..");
            }
            // 切图 key:200/540.. 尺寸
            if(size!=null){
                Thumbnails.of(is).size(size,size).toFile(toFile);
                //二级目录 key:string
            }else{
                FileUtils.copyToFile(is,toFile);
            }
        }
        if(StringUtils.isNotBlank(key)){
            return String.format("%s%s/%s",initDirectory,key,fileName);
        }
        return String.format("%s/%s",initDirectory,fileName);
    }

    /**
     * 创建文件夹
     * @param initDir 初始化目录
     * @param key 二级目录
     * @return
     */
    @Deprecated/** 电器项目照搬过来.*/
    public static File notExistMkdirs(String initDir , String key) {
        File file = null;
        if(StringUtils.isNotBlank(key)){
            file = new File(String.format("%s%s/%s",fileUploadUtils.uploadPath, initDir, key));
        }else {
            file = new File(String.format("%s%s",fileUploadUtils.uploadPath,initDir));
        }
        if(!file.exists()){
            if(!file.mkdirs()){
                log.error("文件创建失败...");
                throw new RuntimeException("上传图片失败...");
            }
        }
        return file;

    }

    /**
     *
     * @param imgPaths  删除的path 集合（只能删除支持的image格式）
     */
    public static void removeImgs(List<String> imgPaths){

        imgPaths.forEach(path -> {
            File file = new File(String.format("%s%s", fileUploadUtils.uploadPath, path));
            removeCheck(file);
            file.delete();
        });
    }

    /**
     *
     * @param imgPath  删除img path
     */
    public static void  removeImg(String imgPath){
        File file = new File(String.format("%s%s", fileUploadUtils.uploadPath, imgPath));
        removeCheck(file);
        file.delete();
    }

    @Deprecated /** 电器项目照搬过来.*/
    private static void removeCheck(File file) {
        if(file.isDirectory()){
            throw new IllegalArgumentException("The deleted file cannot be a folder.");
        }
        // 是否支持格式
        String[] split = file.getName().split("\\.");
        String suffix = split[split.length - 1];
        Boolean isSupport = Boolean.FALSE;
        Map<String, String> supportType = fileUploadUtils.imgConstant.imgSupportType;
        for (String key : supportType.keySet()){
            if(key.equalsIgnoreCase(suffix)){
                isSupport = true;
            }
        }
        if(!isSupport){
            throw new IllegalArgumentException("Delete file format does not match..");
        }
    }


    private static boolean isBase64(String str) {
        if (str == null || str.trim().length() == 0) {
                return false;
            } else {
                if (str.length() % 4 != 0) {
                    return false;
                }

                char[] strChars = str.toCharArray();
                for (char c : strChars) {
                    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
                            || c == '+' || c == '/' || c == '=') {
                        continue;
                    } else {
                        return false;
                    }
                }
            return true;
        }
    }

    public static MultipartFile stringToMultipartFile(String imgStr) {
        byte[] bytes = verify_Formatter(imgStr);
        if (bytes!=null && bytes.length>0){
            return new MockMultipartFile(UUID.randomUUID().toString().replaceAll("-",""),bytes);
        }
        return null;
    }

    public static byte[] verify_Formatter(String imgStr) {
        if(imgStr.startsWith("http://")||imgStr.startsWith("HTTP://")){
            return new byte[0];
        }
        String prefix = ";base64,";
        int index = imgStr.indexOf(prefix);
        if(index>0){
            imgStr = imgStr.substring(index+prefix.length());
        }
        Assert.isTrue(isBase64(imgStr),"上传文件base64格式不正确.");

        return Base64Utils.decodeFromString(imgStr);
    }
}

